#include <soar.h>

#define TRANSFER_SIZE		(64)

typedef struct
{
    unsigned int thrd_id;
	SOCKET sock;
} thrd_ctl_t;
thrd_ctl_t thrd_ctl;

void *thrd_server(thrd_ctl_t *thrd_ctl);

int main()
{
    SOCKET sock[2]; 
    char *buf=NULL;
    int msg_size;
    int count;

	ALLOC_MULTI(buf, char, TRANSFER_SIZE+10, ERROR_OUT);

    if(sock_local_pair(sock) != 0)
    {
        get_last_error(buf);
        printf("socketpair: fail %s\n", buf);
        return(-1);
    }

	thrd_ctl.sock=sock[1];
    if(thrd_create((THRD_FUNC_T)thrd_server,
                (void *)&thrd_ctl, THRD_DETACH,
                &thrd_ctl.thrd_id))
    {
        get_last_error(buf);
        printf("pthread_create: fail %s\n", buf);
        return(-1);
    }

    count=0;
    while(count < 1000000)
    {
        memset(buf, '0', TRANSFER_SIZE);
        msg_size=strlen(buf);
        if(sock_write(sock[0], (unsigned char *)buf, &msg_size,
                    -1, WRAP))
        {
            printf("client: sock_write fail\n");
            return(-1);
        }
        memset(buf, ZERO, sizeof(buf));
        if(sock_read(sock[0], (unsigned char *)buf, &msg_size,
                    -1, WRAP))
        {
            printf("client: sock_read fail\n");
            return(-1);
        }
        buf[msg_size]=ZERO;

        count++;
		if(count % 10000 == 0)
			printf("%d finished\n", count);
    }
    //printf("msg: %s\n", buf);
    sleep(3);

    return(0);

ERROR_OUT:
	return(-1);
}


void *thrd_server(thrd_ctl_t *thrd_ctl)
{
    char *buf;
    int msg_size;

	ALLOC_MULTI(buf, char, TRANSFER_SIZE, ERROR_OUT);

    while(1)
    {
        if(sock_read(thrd_ctl->sock, (unsigned char *)buf, &msg_size,
                    -1, WRAP))
        {
            printf("server: sock_read fail\n");
            return(NULL);
        }
        if(sock_write(thrd_ctl->sock, (unsigned char *)buf, &msg_size,
                    -1, WRAP))
        {
            printf("server: sock_write fail\n");
            return(NULL);
        }
        buf[msg_size]=ZERO;
    }

ERROR_OUT:
    return(NULL);
}
